; On Lisp - Chapter 2, page 13
(defun our-remove-if (fn lst)
  (labels ((traverse (fn lst &optional acc)
                     (if (car lst)
                       (let ((x (car lst)))
                         (if (not (funcall fn x))
                           (push x acc))
                         (traverse fn (cdr lst) acc))
                       acc))) 
    (nreverse (traverse fn lst))))
                             
;Section 2.6, Closures Page 18
(defun list+ (lst n)
  (mapcar #'(lambda (x)
              (+ x n))
          lst))

;Section 2.6, Closures Page 19
(defun make-adderb (n)
  #'(lambda (x &optional change)
      (if change 
          (setq n x))
      (+ x n)))

;Section 2.6, Closures Page 19 - Closurs sharing same data object.
(defun make-dbms (alist)
  (let ((query #'(lambda (x)
                   (assoc x alist)))
        (add #'(lambda (key val)
                 (push (cons key val) alist)))
        (del #'(lambda (key)
                 (setf alist (delete key alist :key #'car)))))
    (list query add del)))
          
;Section 2.7; Local Functions - count-instances 
(defun count-instances (var lst)
  (labels ((count-in (l)
                     (cond ((null l) 0)
                           ((eql var (car l))(1+ (count-in (cdr l))))
                           (t (count-in (cdr l))))))
    (mapcar #'count-in lst)))

;Section 2.8; Tail Recursion
(defun our-length (lst &optional (cnt 0))
  (if (null lst)
    cnt 
    (our-length (cdr lst) (+ 1 cnt))))

;Section 2.8; Sum-1-to-n
(defun sum-of-N (n)
  (labels ((rec (n acc)
                (if (eql n 0)
                  acc
                  (rec (- n 1) (+ acc n)))))
    (rec n 0)))


